package com.bluedot.www.core.utils;

import com.bluedot.www.core.pojo.DO.HandwritingFeature;

import java.awt.image.BufferedImage;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Map;

/**
 * 算法类
 *
 * @author GUOZHIPENG
 * @version 1.0
 * @date 2021/8/7 19:40
 */
public class AlgorithmCutoverUtils {
    /**
     * 默认算法位置
     */
    private static final String DEFAULT_PATH = "Pre_Algorithm-1.0-SNAPSHOT.jar";
    /**
     * 默认算法全限定类名
     */
    private static final String DEFAULT_JAR = "com.baiye.www.AlgorithmHandler";
    /**
     * 默认预处理算法方法名
     */
    private static final String PRE_METHOD_NAME = "preHandleImage";
    /**
     * 默认分析算法方法名
     */
    private static final String HANDLER_METHOD_NAME = "analyzeHandleImage";

    /**
     * 使用指定预处理算法
     *
     * @param bufferedImage 需要处理的图片
     * @param path          算法路径
     * @return java.awt.image.BufferedImage 结果图片
     */
    public static BufferedImage preAlgorithm(BufferedImage bufferedImage, String path) {
        try {
            path = AlgorithmCutoverUtils.class.getClassLoader().getResource("/").getPath().replace("classes", "") + "lib/" + path;
            //path = "D:\\test.jar";
            File file = new File(path);
            URL url = file.toURL();
            URLClassLoader loader = new URLClassLoader(new URL[]{url});
            Class clazz = loader.loadClass(DEFAULT_JAR);
            Object o = clazz.newInstance();
            Method method = clazz.getDeclaredMethod(PRE_METHOD_NAME, BufferedImage.class);
            return (BufferedImage) method.invoke(o, bufferedImage);
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException | MalformedURLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 使用默认预处理算法
     *
     * @param bufferedImage 需要处理的图片
     * @return java.awt.image.BufferedImage 结果图片
     * @author GUOZHIPENG
     * @date 2021/8/15 10:29
     */
    public static BufferedImage defaultPreAlgorithm(BufferedImage bufferedImage) {
        return preAlgorithm(bufferedImage, DEFAULT_PATH);
    }

    /**
     * 指定处理算法
     *
     * @param bufferedImage 需要处理的图片
     * @param path          算法路径
     * @return java.util.Map 结果
     * @author GUOZHIPENG
     * @date 2021/8/15 10:33
     */
    public static HandwritingFeature handlerAlgorithm(BufferedImage bufferedImage, String path) {
        if (path == null) {
            return defaultHandlerAlgorithm(bufferedImage);
        }
        try {
            path = AlgorithmCutoverUtils.class.getClassLoader().getResource("/").getPath().replace("classes", "") + "lib/" + path;
            File file = new File(path);
            URL url = file.toURL();
            URLClassLoader loader = new URLClassLoader(new URL[]{url});
            Class clazz = loader.loadClass(DEFAULT_JAR);
            Object o = clazz.newInstance();
            Method method = clazz.getDeclaredMethod(HANDLER_METHOD_NAME, BufferedImage.class);
            Map<String, Object> map = (Map<String, Object>) method.invoke(o, bufferedImage);
            return map2bean(map, HandwritingFeature.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 使用默认处理算法
     *
     * @param bufferedImage
     * @return java.util.Map
     * @author GUOZHIPENG
     * @date 2021/8/15 10:35
     */
    public static HandwritingFeature defaultHandlerAlgorithm(BufferedImage bufferedImage) {
        return handlerAlgorithm(bufferedImage, DEFAULT_PATH);
    }

    public static <T> T map2bean(Map<String, Object> map, Class<T> clz) throws Exception {
        //创建一个需要转换为的类型的对象
        T obj = clz.newInstance();
        //从Map中获取和属性名称一样的值，把值设置给对象(setter方法)

        //得到属性的描述器
        BeanInfo b = Introspector.getBeanInfo(clz, Object.class);
        PropertyDescriptor[] pds = b.getPropertyDescriptors();
        for (PropertyDescriptor pd : pds) {
            //得到属性的setter方法
            Method setter = pd.getWriteMethod();
            //得到key名字和属性名字相同的value设置给属性

            setter.invoke(obj, map.get(pd.getName().replaceFirst(pd.getName().charAt(0)+"",
                    Character.toUpperCase(pd.getName().charAt(0))+"")));
        }
        return obj;
    }

    public static void main(String[] args) {
        AlgorithmCutoverUtils.defaultPreAlgorithm(null);
    }
}
